package com.exchange.controller;

import com.exchange.dto.MerchantDto;
import com.exchange.dto.UserDto;
import com.exchange.entity.Merchant;
import com.exchange.entity.User;
import com.exchange.service.MerchantService;
import com.exchange.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;

import java.util.List;
import java.util.Optional;

@RestController
@RequestMapping("/api/admin")
@CrossOrigin(origins = "*")
@PreAuthorize("hasRole('ADMIN')")
public class AdminController {
    
    @Autowired
    private UserService userService;
    
    @Autowired
    private MerchantService merchantService;
    
    // Get all merchants
    @GetMapping("/merchants")
    public ResponseEntity<List<UserDto>> getAllMerchants() {
        // In a real implementation, we'd have a method to get all merchant users
        // For now, this is a placeholder
        return ResponseEntity.ok(List.of());
    }
    
    // Get merchant by ID
    @GetMapping("/merchants/{id}")
    public ResponseEntity<MerchantDto> getMerchant(@PathVariable Long id) {
        return merchantService.findById(id)
                .map(ResponseEntity::ok)
                .orElse(ResponseEntity.notFound().build());
    }
    
    // Update merchant subscription and limits
    @PutMapping("/merchants/{id}")
    public ResponseEntity<MerchantDto> updateMerchant(@PathVariable Long id, @RequestBody AdminMerchantUpdateRequest request) {
        Optional<MerchantDto> existingMerchant = merchantService.findById(id);
        if (existingMerchant.isPresent()) {
            // Get the existing merchant details
            Merchant merchantDetails = new Merchant();
            merchantDetails.setBusinessName(request.getBusinessName());
            merchantDetails.setBusinessLicense(request.getBusinessLicense());
            merchantDetails.setContactPerson(request.getContactPerson());
            merchantDetails.setAddress(request.getAddress());
            merchantDetails.setSubscriptionType(request.getSubscriptionType());
            merchantDetails.setSubscriptionStartDate(request.getSubscriptionStartDate());
            merchantDetails.setSubscriptionEndDate(request.getSubscriptionEndDate());
            merchantDetails.setMaxProducts(request.getMaxProducts());
            merchantDetails.setMaxExchangeCodes(request.getMaxExchangeCodes());
            merchantDetails.setMaxOrdersPerMonth(request.getMaxOrdersPerMonth());
            
            MerchantDto updatedMerchant = merchantService.updateMerchant(id, merchantDetails);
            return ResponseEntity.ok(updatedMerchant);
        }
        return ResponseEntity.notFound().build();
    }
    
    // Activate or deactivate a merchant
    @PutMapping("/merchants/{id}/status")
    public ResponseEntity<MerchantDto> updateMerchantStatus(@PathVariable Long id, @RequestBody StatusUpdateRequest request) {
        Optional<MerchantDto> existingMerchant = merchantService.findById(id);
        if (existingMerchant.isPresent()) {
            // Get user associated with merchant
            UserDto userDto = userService.findByUsername(
                userService.findByEmail(existingMerchant.get().getUserId().toString()).map(UserDto::getEmail).orElse("")
            ).orElse(null);
            
            if (userDto != null) {
                // Update user status
                User user = new User();
                user.setId(userDto.getId());
                user.setUsername(userDto.getUsername());
                user.setEmail(userDto.getEmail());
                user.setPhone(userDto.getPhone());
                user.setUserType(userDto.getUserType());
                user.setStatus(request.isActive() ? User.UserStatus.ACTIVE : User.UserStatus.INACTIVE);
                
                // In a real system, you'd have a method to update user status
            }
            
            // Update merchant status by updating subscription
            Merchant merchantDetails = new Merchant();
            merchantDetails.setBusinessName(existingMerchant.get().getBusinessName());
            merchantDetails.setBusinessLicense(existingMerchant.get().getBusinessLicense());
            merchantDetails.setContactPerson(existingMerchant.get().getContactPerson());
            merchantDetails.setAddress(existingMerchant.get().getAddress());
            merchantDetails.setSubscriptionType(existingMerchant.get().getSubscriptionType());
            merchantDetails.setSubscriptionStartDate(existingMerchant.get().getSubscriptionStartDate());
            merchantDetails.setSubscriptionEndDate(request.isActive() ? existingMerchant.get().getSubscriptionEndDate() : 
                java.time.LocalDate.now()); // Set end date to now if deactivating
            merchantDetails.setMaxProducts(existingMerchant.get().getMaxProducts());
            merchantDetails.setMaxExchangeCodes(existingMerchant.get().getMaxExchangeCodes());
            merchantDetails.setMaxOrdersPerMonth(existingMerchant.get().getMaxOrdersPerMonth());
            
            MerchantDto updatedMerchant = merchantService.updateMerchant(id, merchantDetails);
            return ResponseEntity.ok(updatedMerchant);
        }
        return ResponseEntity.notFound().build();
    }
    
    // Delete a merchant (soft delete in a real system)
    @DeleteMapping("/merchants/{id}")
    public ResponseEntity<Void> deleteMerchant(@PathVariable Long id) {
        // In a real implementation, this would be a soft delete
        // For now, this is a placeholder
        return ResponseEntity.ok().build();
    }
    
    // Request classes
    public static class AdminMerchantUpdateRequest {
        private String businessName;
        private String businessLicense;
        private String contactPerson;
        private String address;
        private Merchant.SubscriptionType subscriptionType;
        private java.time.LocalDate subscriptionStartDate;
        private java.time.LocalDate subscriptionEndDate;
        private Integer maxProducts;
        private Integer maxExchangeCodes;
        private Integer maxOrdersPerMonth;
        
        // Getters and setters
        public String getBusinessName() { return businessName; }
        public void setBusinessName(String businessName) { this.businessName = businessName; }
        
        public String getBusinessLicense() { return businessLicense; }
        public void setBusinessLicense(String businessLicense) { this.businessLicense = businessLicense; }
        
        public String getContactPerson() { return contactPerson; }
        public void setContactPerson(String contactPerson) { this.contactPerson = contactPerson; }
        
        public String getAddress() { return address; }
        public void setAddress(String address) { this.address = address; }
        
        public Merchant.SubscriptionType getSubscriptionType() { return subscriptionType; }
        public void setSubscriptionType(Merchant.SubscriptionType subscriptionType) { this.subscriptionType = subscriptionType; }
        
        public java.time.LocalDate getSubscriptionStartDate() { return subscriptionStartDate; }
        public void setSubscriptionStartDate(java.time.LocalDate subscriptionStartDate) { this.subscriptionStartDate = subscriptionStartDate; }
        
        public java.time.LocalDate getSubscriptionEndDate() { return subscriptionEndDate; }
        public void setSubscriptionEndDate(java.time.LocalDate subscriptionEndDate) { this.subscriptionEndDate = subscriptionEndDate; }
        
        public Integer getMaxProducts() { return maxProducts; }
        public void setMaxProducts(Integer maxProducts) { this.maxProducts = maxProducts; }
        
        public Integer getMaxExchangeCodes() { return maxExchangeCodes; }
        public void setMaxExchangeCodes(Integer maxExchangeCodes) { this.maxExchangeCodes = maxExchangeCodes; }
        
        public Integer getMaxOrdersPerMonth() { return maxOrdersPerMonth; }
        public void setMaxOrdersPerMonth(Integer maxOrdersPerMonth) { this.maxOrdersPerMonth = maxOrdersPerMonth; }
    }
    
    public static class StatusUpdateRequest {
        private boolean active;
        
        public boolean isActive() { return active; }
        public void setActive(boolean active) { this.active = active; }
    }
}